package com.jgp.sys.query.jpa;

import com.jgp.common.persistence.Model;
import com.jgp.common.utils.ScannerUtil;
import com.jgp.sys.query.power.DataPowerConfig;
import lombok.extern.log4j.Log4j2;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目   jgp-cloud-parent
 * 作者   loufei
 * 时间   2019-11-10
 */
@Log4j2
public class DataFilterBuilder {
    
    private static Set<DataFilter> filters = new HashSet<>();
    private static ClientFilter clientFilter = null;
    
    public DataFilterBuilder() {
        log.trace("开始扫描数据过滤器。。。");
        Set<Class<Object>> classes = ScannerUtil.scanBySuperClass(new Class[]{DataFilter.class, ClientFilter.class}, "com.jgp.*.jpa.filters");
        log.trace("共扫描："+classes.size());
        classes.forEach(clazz->{
            try {
                if(DataFilter.class.isAssignableFrom(clazz)){
                    this.filters.add((DataFilter)clazz.newInstance());
                }else if(ClientFilter.class.isAssignableFrom(clazz)){
                    this.clientFilter = (ClientFilter)clazz.newInstance();
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("数据过滤器实例化错误！",e);
            }
        });
    }
    
    public Predicate clientFilter(Root<? extends Model> root, CriteriaBuilder builder){
        return this.clientFilter.doPredicate(root,builder);
    }
    
    public List<Predicate> doFilters(Root<? extends Model> root, CriteriaQuery<?> query, CriteriaBuilder builder, DataPowerConfig powerConfig){
        if(filters.size() == 0) return new ArrayList<>();
        List<Predicate> predicates = new ArrayList<>();
        for (DataFilter filter : filters) {
            predicates.add(filter.doPredicate(root, query, builder,powerConfig));
        }
        return predicates.stream().filter(Objects::nonNull).collect(Collectors.toList());
    }
    
    public String clientId(Class javaType) {
        if(Objects.nonNull(this.clientFilter)){
            return this.clientFilter.getClientId(javaType);
        }else{
            return null;
        }
    }
}
